package com.ciaojian.bytedance.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ciaojian.core.bytedance.auth.ByteDanceTokenProvider;
import com.ciaojian.bytedance.vo.bytedance.CallBackResponse;
import com.ciaojian.bytedance.vo.bytedance.ReceiveOrderQuery;
import com.ciaojian.core.bytedance.ByteDanceMiniConfig;
import com.ciaojian.core.bytedance.ByteDancePayConfig;
import com.ciaojian.core.bytedance.ByteDanceSignUtil;
import com.ciaojian.core.enums.business.*;
import com.ciaojian.core.mapper.CouponCodeMapper;
import com.ciaojian.core.mapper.DyOrderMapper;
import com.ciaojian.core.mapper.OrderMapper;
import com.ciaojian.core.mapper.UserMapper;
import com.ciaojian.core.model.Order;
import com.ciaojian.core.model.dy.DyOrder;
import com.ciaojian.core.model.vo.ByteDanceDeliveryVo;
import com.ciaojian.core.service.CouponService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class ByteDanceNotifyService {

    @Resource
    private DyOrderMapper dyOrderMapper;

    @Resource
    private UserMapper userMapper;
    @Resource
    private CouponService couponService;
    @Resource
    private CouponCodeMapper couponCodeMapper;

    @Resource
    private OrderMapper orderMapper;
    @Autowired
    private ByteDanceTokenProvider byteDanceTokenProvider;
    @Resource
    private ByteDanceMiniAppAuthService byteDanceMiniAppAuthService;

    public Object receiveTicket(ReceiveOrderQuery receiveOrderQuery) {
        log.info("接收支付异步通知请求：{}",receiveOrderQuery);
        CallBackResponse callBackResponse=new CallBackResponse();
        if ("payment".equals(receiveOrderQuery.getType())) {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                JsonNode msgNode = objectMapper.readTree(receiveOrderQuery.getMsg());
                if (msgNode == null) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("支付成功回调msg内容为空！");
                    return callBackResponse;
                }
                String appId = msgNode.has("app_id") ? msgNode.get("app_id").asText() : ""; // 小程序AppID
                if (StringUtils.isBlank(appId)) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("回调参数有误，appid不能为空！");
                    return callBackResponse;
                }

                String orderId = msgNode.has("order_id") ? msgNode.get("order_id").asText() : ""; // 订单号
                if (StringUtils.isBlank(orderId)) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("回调参数有误，status不能为空！");
                    return callBackResponse;
                }

                QueryWrapper<DyOrder> dyOrderQueryWrapper = new QueryWrapper<DyOrder>();
                dyOrderQueryWrapper.eq("dy_order_id", orderId);

                DyOrder dyOrder = dyOrderMapper.selectOne(dyOrderQueryWrapper);

                String status = msgNode.has("status") ? msgNode.get("status").asText() : ""; // 支付状态
                if (StringUtils.isBlank(status)) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("回调参数有误，orderId不能为空！");
                    return callBackResponse;
                }else if (status.equals("SUCCESS")){

                    dyOrder.setStatus(3);

                    BigDecimal price = new BigDecimal(msgNode.get("total_amount").asInt());
                    price = price.divide(new BigDecimal(100), 2, BigDecimal.ROUND_UNNECESSARY);
                    dyOrder.setPayTotal(price); //支付金额

                    int pay_channel = msgNode.get("pay_channel").asInt();
                    if (pay_channel==1){
                        dyOrder.setPayType("微信支付");// 支付渠道
                    }else if (pay_channel==2){
                        dyOrder.setPayType("支付宝支付");
                    }else if (pay_channel==3){
                        dyOrder.setPayType("银行卡支付");
                    }else if (pay_channel==10){
                        dyOrder.setPayType("抖音支付");
                    }

                    dyOrder.setPayId(msgNode.has("channel_pay_id") ? msgNode.get("channel_pay_id").asText() : "");//渠道支付单号
                    Date event_time = new Date(msgNode.get("event_time").asLong());
                    dyOrder.setPayTime(event_time);
                    JsonNode coupon_code_id = msgNode.get("cp_extra");
                    JsonNode jsonNode = objectMapper.readTree(coupon_code_id.asText());
                    int couponCodeId = jsonNode.has("coupon_code_id") ? jsonNode.get("coupon_code_id").asInt() : 0;
                    dyOrder.setCouponId(couponCodeId);

                    int memberId = jsonNode.has("member_id") ? jsonNode.get("member_id").asInt() : 0;
                    dyOrder.setMemberId(memberId);

                    /**
                     * 发券
                     */
//                    User user = userMapper.selectById(dyOrder.getUserId());
//                    if (ObjectUtil.isNotNull(user)){
//                        //已经登陆过潮剪小程序的用户
//                        QueryWrapper<CouponCode> couponCodeQueryWrapper = new QueryWrapper<>();
//                        couponCodeQueryWrapper.eq("user_id",user.getId());
//                        couponCodeQueryWrapper.eq("coupon_id",469);
//                        List<CouponCode> couponCodes = couponCodeMapper.selectList(couponCodeQueryWrapper);
//                        if (couponCodes.size()>0){
//                            //暂不做操作
//                        }else {
//                            //券码号
//                            String[] couponCodeIds = couponCodeId.split(",");
//                            if (couponCodeIds.length > 0) {
//                                for (String codeId : couponCodeIds) {
//
//                                    dyOrder.setCouponId(couponCodeId);
//
//                                    QueryWrapper<CouponCode> queryWrapper = new QueryWrapper<>();
//                                    queryWrapper.eq("coupon_id", codeId)
//                                            .eq("status", 0)
//                                            .isNull("user_id")
//                                            .last("limit 1");
//                                    CouponCode couponCode = new CouponCode().selectOne(queryWrapper);
//                                    Assert.notNull(couponCode, "券码已被抢完");
//
//                                    couponCode.setStatus(1);
//                                    couponCode.setUserId(user.getId());
//                                    couponCode.setOrigin(CouponCodeOriginEnum.DOUYIN_WRITE_OFF);
//                                    couponCode.setExpiredTime(couponService.getCouponExpiredTime(Integer.parseInt(codeId)));
//                                    couponCode.setUpdateTime(new Date());
//                                    couponCode.setRemark(dyOrder.getDyOrderId());
//                                    boolean b = couponCode.updateById();
//                                    couponService.addGetNum(Integer.parseInt(codeId));
//
//                                    CouponCodeTakeRecord couponCodeTakeRecord = new CouponCodeTakeRecord();
//                                    couponCodeTakeRecord.setUserId(user.getId());
//                                    couponCodeTakeRecord.setCouponId(Integer.parseInt(codeId));
//                                    couponCodeTakeRecord.setCouponCode(couponCode.getCode());
//                                    couponCodeTakeRecord.setActivityId(4);
//                                    couponCodeTakeRecord.setType(CouponCodeTakeRecordTypeEnum.DOUYIN_WRITE_OFF);
//                                    couponCodeTakeRecord.insert();
//                                    if (b) {
//                                        dyOrder.setStatus(4);
//                                        dyOrder.setCouponCode(couponCode.getCode());
//                                    }
//
//                                }
//                            }
//                        }
//                    }


                }else if (status.equals("CANCEL")){
                    dyOrder.setStatus(2);
                    dyOrder.setCancelReason(msgNode.has("message") ? msgNode.get("message").asText() : ""); //取消原因
                }
                dyOrder.setUpdateTime(new Date());


                dyOrderMapper.updateById(dyOrder);

            } catch (IOException e) {
                log.error(e.getMessage(),e);
            }
        }
        //成功返回
        callBackResponse.setErr_no(0);
        callBackResponse.setErr_tips("success");
        return callBackResponse;
    }



    public Object jianfaWxNotify(ReceiveOrderQuery receiveOrderQuery) {

        log.info("接收支付异步通知请求：{}",receiveOrderQuery);
        CallBackResponse callBackResponse=new CallBackResponse();
        if ("payment".equals(receiveOrderQuery.getType())) {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                JsonNode msgNode = objectMapper.readTree(receiveOrderQuery.getMsg());
                if (msgNode == null) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("支付成功回调msg内容为空！");
                    return callBackResponse;
                }
                String appId = msgNode.has("appid") ? msgNode.get("appid").asText() : ""; // 小程序AppID
                if (StringUtils.isBlank(appId)) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("回调参数有误，appid不能为空！");
                    return callBackResponse;
                }

                String orderNo = msgNode.has("cp_orderno") ? msgNode.get("cp_orderno").asText() : ""; // 订单号
                if (StringUtils.isBlank(orderNo)) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("回调参数有误，订单号不能为空！");
                    return callBackResponse;
                }

                QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<Order>();
                orderQueryWrapper.eq("order_no", orderNo);

                Order order = orderMapper.selectOne(orderQueryWrapper);

                String status = msgNode.has("status") ? msgNode.get("status").asText() : ""; // 支付状态
                if (StringUtils.isBlank(status)) {
                    callBackResponse.setErr_no(1);
                    callBackResponse.setErr_tips("回调参数有误，status不能为空！");
                    return callBackResponse;
                }else if (status.equals("SUCCESS")) {

                    order.setStatus(OrderStatusEnum.paid);

                    BigDecimal price = new BigDecimal(msgNode.get("total_amount").asInt());
                    price = price.divide(new BigDecimal(100), 2, BigDecimal.ROUND_UNNECESSARY);
                    order.setPayTotal(price); //支付金额

                    int pay_channel = msgNode.get("way").asInt();
                    if (pay_channel == 1) {
                        order.setPayType("微信支付");// 支付渠道
                    } else if (pay_channel == 2) {
                        order.setPayType("支付宝支付");
                    } else if (pay_channel == 3) {
                        order.setPayType("银行卡支付");
                    } else if (pay_channel == 10) {
                        order.setPayType("抖音支付");
                    }

                    long paid_at = msgNode.get("paid_at").asLong();
                    long l = paid_at * 1000;
                    Date event_time = new Date(l);
                    order.setPayTime(event_time);



                    orderMapper.updateById(order);

                }
            } catch (IOException e) {
                log.error(e.getMessage(),e);
            }
        }
        //成功返回
        callBackResponse.setErr_no(0);
        callBackResponse.setErr_tips("success");
        return callBackResponse;
    }

    public JSONObject pushDeliveryMiniApp(Integer orderId) {

        //定义接收数据
        JSONObject result = new JSONObject();
//        List<Integer> ids = dyOrderMapper.dspk();
//        for (Integer id : ids) {
//            orderId = id;
            DyOrder order = dyOrderMapper.selectById(orderId);
            JSONObject param = new JSONObject();
            ByteDanceDeliveryVo.ItemOrderListBean itemOrderListBean = new ByteDanceDeliveryVo.ItemOrderListBean();
            itemOrderListBean.setItem_order_id(order.getOrderNo());
            List<ByteDanceDeliveryVo.ItemOrderListBean> itemOrderListBeans = new ArrayList<>();
            itemOrderListBeans.add(itemOrderListBean);

            param.put("out_order_no", order.getOrderNo());
            param.put("use_all", true);
            param.put("item_order_list", itemOrderListBeans);
            //默认写死
            param.put("poi_info", "{\"shop_name\":\"潮剪(东方宝泰店)\",\"ext_valid_shop_id\":\"6729124296515487756\",\"valid_poi_id_str\":\"7\"}");

            String bytedance_clienttoken = byteDanceTokenProvider.getBytedanceClienttoken("BYTEDANCE_CLIENTTOKEN_MINI");
//        String bytedance_miniapp_accesstoken = byteDanceTokenProvider.getBytedanceClienttoken("BYTEDANCE_MINIAPP_ACCESSTOKEN");
            try {
                HttpPost httpPost = new HttpPost(ByteDancePayConfig.PUSH_DELIVERY_V21);
                CloseableHttpClient client = HttpClients.createDefault();
                StringEntity entity = new StringEntity(param.toString(), "UTF-8");

                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);


                long timestamp = System.currentTimeMillis() / 1000;
                String signature = ByteDanceSignUtil.getSignature("POST", "/api/apps/trade/v2/push_certificate_delivery", timestamp, param.toJSONString());

                String sign = " " +
                        "" + ByteDanceMiniConfig.BYTE_AUTHORIZATION + " " +
                        "appid=\"" + ByteDanceMiniConfig.APP_ID + "\"," +
                        "nonce_str=\"" + ByteDanceMiniConfig.NONCE_STR + "\"," +
                        "timestamp=\"" + timestamp + "\"," +
                        "key_version=\"1\"," +
                        "signature=\"" + signature + "\"";

                httpPost.setHeader("Byte-Authorization", sign);
                httpPost.setHeader("Content-Type", "application/json");
                httpPost.setHeader("access-token",bytedance_clienttoken);

                HttpResponse dyResponse = client.execute(httpPost);
                if (dyResponse.getStatusLine().getStatusCode() == 200) {
                    result = JSON.parseObject(EntityUtils.toString(dyResponse.getEntity(), "UTF-8"));
                    com.ciaojian.core.model.vo.CallBackResponse callBackResponse = result.toJavaObject(com.ciaojian.core.model.vo.CallBackResponse.class);
                    if (callBackResponse.getErr_tips().equals("success")) {
                        order.setStatus(5);
                        order.setVefiTime(new Date());
                        order.updateById();
                    }
                }
            }catch (Exception e){

            }
//        }

        return result;
    }

    public JSONObject pushDelivery(Integer orderId) {
        DyOrder order = dyOrderMapper.selectById(orderId);
        //定义接收数据
        JSONObject result = new JSONObject();
        JSONObject param = new JSONObject();
        ByteDanceDeliveryVo.ItemOrderListBean itemOrderListBean = new ByteDanceDeliveryVo.ItemOrderListBean();
        itemOrderListBean.setItem_order_id(order.getOrderNo());
        List<ByteDanceDeliveryVo.ItemOrderListBean> itemOrderListBeans = new ArrayList<>();
        itemOrderListBeans.add(itemOrderListBean);

        param.put("out_order_no", order.getOrderNo());
        param.put("use_all", true);
        param.put("item_order_list", itemOrderListBeans);
        //默认写死
        param.put("poi_info", "{\"shop_name\":\"潮剪(东方宝泰店)\",\"ext_valid_shop_id\":\"6729124296515487756\",\"valid_poi_id_str\":\"7\"}");

        String bytedance_clienttoken = byteDanceTokenProvider.getBytedanceClienttoken("BYTEDANCE_CLIENTTOKEN_MINI");
        try {
            HttpPost httpPost = new HttpPost(ByteDancePayConfig.PUSH_DELIVERY_V2);
            CloseableHttpClient client = HttpClients.createDefault();
            StringEntity entity = new StringEntity(param.toString(), "UTF-8");

            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);


            long timestamp = System.currentTimeMillis() / 1000;
            String signature = ByteDanceSignUtil.getSignature("POST", "/api/apps/trade/v2/fulfillment/push_delivery", timestamp, param.toJSONString());

            String sign = " " +
                    "" + ByteDanceMiniConfig.BYTE_AUTHORIZATION + " " +
                    "appid=\"" + ByteDanceMiniConfig.APP_ID + "\"," +
                    "nonce_str=\"" + ByteDanceMiniConfig.NONCE_STR + "\"," +
                    "timestamp=\"" + timestamp + "\"," +
                    "key_version=\"1\"," +
                    "signature=\"" + signature + "\"";

            httpPost.setHeader("Byte-Authorization", sign);
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("access-token",bytedance_clienttoken);


            HttpResponse dyResponse = client.execute(httpPost);
            if (dyResponse.getStatusLine().getStatusCode() == 200) {
                result = JSON.parseObject(EntityUtils.toString(dyResponse.getEntity(), "UTF-8"));
                com.ciaojian.core.model.vo.CallBackResponse callBackResponse = result.toJavaObject(com.ciaojian.core.model.vo.CallBackResponse.class);
                if (callBackResponse.equals("success")) {
                    order.setStatus(5);
                    order.setVefiTime(new Date());
                    order.updateById();
                }
            }
        }catch (Exception e){

        }
        return result;
    }
}
